package com.yy.wga.order.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.yy.wga.common.core.dto.PageBean;
import com.yy.wga.common.core.enmus.EResponseCode;
import com.yy.wga.common.core.exception.BusinessException;
import com.yy.wga.common.mysql.util.PageUtil;
import com.yy.wga.common.util.aop.DistributedLock;
import com.yy.wga.common.util.common.StringUtils;
import com.yy.wga.common.utils.mapping.BeansUtils;
import com.yy.wga.common.web.intereceptor.RequestHolder;
import com.yy.wga.order.feign.request.OrderUpgradePageRequest;
import com.yy.wga.order.feign.response.OrderDeliveryAddressSaveRequest;
import com.yy.wga.order.feign.response.OrderUpgradePageResponse;
import com.yy.wga.order.service.mapper.OrderUpGradeMapper;
import com.yy.wga.order.service.pojo.OrderDeliveryAddressDO;
import com.yy.wga.order.service.pojo.OrderUpGradeDO;
import com.yy.wga.order.service.service.OrderDeliveryAddressService;
import com.yy.wga.order.service.service.OrderUpGradeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 升级礼包商品订单信息(OrderUpGrade)表服务实现类
 *
 * @author guochao
 * @since 2024-12-21 14:56:58
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderUpGradeServiceImpl extends ServiceImpl<OrderUpGradeMapper, OrderUpGradeDO> implements OrderUpGradeService {

    private final ApplicationEventPublisher eventPublisher;
    private final UserSummaryService userSummaryService;
    private final OrderDeliveryAddressService deliveryAddressService;

    @Override
    @Transactional
    @DistributedLock(value = "#update.orderNo")
    public void updateInfo(OrderUpGradeDO update) {
        // 不可取消
        if (update.getStatus() == 5) {
            throw new BusinessException("不可取消");
        }
        if (StringUtils.isBlank(update.getOrderNo())) {
            throw new BusinessException("未传入订单唯一标识");
        }
        OrderUpGradeDO orderUpGrade = super.getOne(new LambdaUpdateWrapper<OrderUpGradeDO>()
                .eq(OrderUpGradeDO::getOrderNo, update.getOrderNo()));
        if (orderUpGrade == null) {
            throw new BusinessException(EResponseCode.SYSTEM_RECORD_NOT_EXIST);
        }
        // 订单状态一致不处理
        if (Objects.equals(update.getStatus(), orderUpGrade.getStatus())) {
            return;
        }

        // 订单状态变更
        if ((update.getStatus() == 2 || update.getStatus() == 3)
                && 1 != orderUpGrade.getStatus()) {
            throw new BusinessException("订单不可转为支付成功状态");
        }
        // 修改数据
        update.setId(orderUpGrade.getId());
        baseMapper.updateById(update);

        try {
            // 已结算状态则进行分佣
            if (update.getStatus().equals(7)) {
                // 服务商复购没有佣金
                if (orderUpGrade.getCommissionValue() > 0) {
                    OrderUpGradeCommissionDTO orderCommissionDTO = new OrderUpGradeCommissionDTO(this);
                    orderCommissionDTO.setAppKey(orderUpGrade.getAppKey());
                    orderCommissionDTO.setGoodsId(orderUpGrade.getGoodsId());
                    orderCommissionDTO.setTitle(orderUpGrade.getTitle());
                    orderCommissionDTO.setHeadImg(orderUpGrade.getHeadImg());
                    orderCommissionDTO.setPayTime(update.getPayTime());
                    orderCommissionDTO.setSuccessTime(update.getPayTime());
                    orderCommissionDTO.setCommissionValue(orderUpGrade.getCommissionValue());
                    orderCommissionDTO.setFromUserId(orderUpGrade.getUserId());
                    orderCommissionDTO.setOrderNo(orderUpGrade.getOrderNo());
                    orderCommissionDTO.setPrice(orderUpGrade.getPrice());
                    orderCommissionDTO.setStatus(7);
                    eventPublisher.publishEvent(orderCommissionDTO);
                    log.info("{}直通车商品完成分佣", orderUpGrade.getOrderNo());
                }

                // 增加用户销售额
                if (orderUpGrade.getUpAwardValue() > 0) {
                    UserSummaryDO userSummaryDO = new UserSummaryDO();
                    userSummaryDO.setAppKey(update.getAppKey());
                    userSummaryDO.setSaleAmount(orderUpGrade.getUpAwardValue());
                    userSummaryDO.setUserId(orderUpGrade.getUserId());
                    userSummaryService.updateInfo(userSummaryDO);
                    log.info("用户{}增加{}销售额", orderUpGrade.getUserId(), orderUpGrade.getUpAwardValue());
                }

                // 触发消费额变更事件，不加销售额代表用户已经是这个等级了
                if (orderUpGrade.getUpAwardValue() > 0) {
                    OrderSettleEvent orderSettleEvent = new OrderSettleEvent(this);
                    orderSettleEvent.setAppKey(orderUpGrade.getAppKey());
                    orderSettleEvent.setUserId(orderUpGrade.getUserId());
                    eventPublisher.publishEvent(orderSettleEvent);

                    // 发送升级消息
                    FirstBuyUpgradeEvent firstBuyUpgradeEvent = new FirstBuyUpgradeEvent(this);
                    firstBuyUpgradeEvent.setAppKey(orderUpGrade.getAppKey());
                    firstBuyUpgradeEvent.setUserId(orderUpGrade.getUserId());
                    firstBuyUpgradeEvent.setUpgradeTime(new Date());
                    eventPublisher.publishEvent(firstBuyUpgradeEvent);
                }
            }
        } catch (Exception e) {
            log.error("用户升级异常:{}", e.getMessage(), e);
            throw new BusinessException(EResponseCode.SYSTEM_BUSY_ERROR);
        }
    }

    @Override
    public PageBean<OrderUpgradePageResponse> pageData(OrderUpgradePageRequest request) {
        // 查询订单
        Long userId = request.getUserId();
        LambdaQueryWrapper<OrderUpGradeDO> queryWrapper = new LambdaQueryWrapper<OrderUpGradeDO>()
                .eq(OrderUpGradeDO::getAppKey, RequestHolder.getBaseRequest().getAppKey())
                .eq(userId != null, OrderUpGradeDO::getUserId, userId)
                .eq(request.getStatus() != null, OrderUpGradeDO::getStatus, request.getStatus())
                .eq(StringUtils.isNotBlank(request.getOrderNo()), OrderUpGradeDO::getOrderNo, request.getOrderNo())
                .gt(request.getStartPayTime() != null, OrderUpGradeDO::getPayTime, request.getStartPayTime())
                .lt(request.getEndPayTime() != null, OrderUpGradeDO::getPayTime, request.getEndPayTime())
                .orderByDesc(OrderUpGradeDO::getId);
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<OrderUpGradeDO> orderGoodsList = baseMapper.selectList(queryWrapper);
        List<OrderUpgradePageResponse> responseList = BeansUtils.mapList(orderGoodsList, OrderUpgradePageResponse.class);

        // 填充信息
        if (!CollectionUtils.isEmpty(responseList)) {
            // 查询收获地址
            Set<String> orderNoSet = responseList.stream()
                    .map(OrderUpgradePageResponse::getOrderNo).collect(Collectors.toSet());
            List<OrderDeliveryAddressDO> deliveryAddressList = deliveryAddressService.list(new LambdaQueryWrapper<OrderDeliveryAddressDO>()
                    .in(OrderDeliveryAddressDO::getAppKey, RequestHolder.getBaseRequest().getAppKey())
                    .in(OrderDeliveryAddressDO::getOrderNo, orderNoSet));
            Map<String, OrderDeliveryAddressDO> deliveryAddressMap = deliveryAddressList.stream()
                    .collect(Collectors.toMap(OrderDeliveryAddressDO::getOrderNo, Function.identity()));

            for (OrderUpgradePageResponse response : responseList) {
                OrderDeliveryAddressDO addressDO = deliveryAddressMap.get(response.getOrderNo());
                response.setDeliveryInfo(BeansUtils.map(addressDO, OrderUpgradePageResponse.DeliveryInfo.class));
            }
        }

        PageBean<OrderUpgradePageResponse> pageBean = PageUtil.setPageInfo(orderGoodsList);
        pageBean.setList(responseList);
        return pageBean;
    }

    @Override
    public void delivery(OrderDeliveryAddressSaveRequest request) {
        this.update(new LambdaUpdateWrapper<OrderUpGradeDO>()
                .eq(OrderUpGradeDO::getAppKey, RequestHolder.getBaseRequest().getAppKey())
                .eq(OrderUpGradeDO::getOrderNo, request.getOrderNo())
                .set(OrderUpGradeDO::getStatus, 4)
                .set(OrderUpGradeDO::getDeliverTime, new Date()));

        deliveryAddressService.update(new LambdaUpdateWrapper<OrderDeliveryAddressDO>()
                .eq(OrderDeliveryAddressDO::getAppKey, RequestHolder.getBaseRequest().getAppKey())
                .eq(OrderDeliveryAddressDO::getOrderNo, request.getOrderNo())
                .set(OrderDeliveryAddressDO::getDeliveryCode, request.getDeliveryCode())
                .set(OrderDeliveryAddressDO::getWaybillNo, request.getWaybillNo()));
    }
}
